import React, { useRef, useEffect, useState } from 'react'
import { Editor, OnMount, OnChange } from '@monaco-editor/react'
import { editor, languages, Position } from 'monaco-editor'
import { useAppSelector } from '@/store'
import { formatSQL } from '@/utils'
import { schemaProvider } from '../SQLEditor/SchemaProvider'

// Doris SQL关键字
const DORIS_KEYWORDS = [
  // 基础关键字
  'SELECT', 'FROM', 'WHERE', 'GROUP', 'BY', 'ORDER', 'HAVING', 'LIMIT', 'OFFSET',
  'INSERT', 'INTO', 'VALUES', 'UPDATE', 'SET', 'DELETE', 'CREATE', 'DROP', 'ALTER',
  'TABLE', 'DATABASE', 'INDEX', 'VIEW', 'PROCEDURE', 'FUNCTION', 'TRIGGER',
  
  // 数据类型
  'INT', 'INTEGER', 'BIGINT', 'SMALLINT', 'TINYINT', 'DECIMAL', 'NUMERIC',
  'FLOAT', 'DOUBLE', 'REAL', 'BOOLEAN', 'BOOL', 'DATE', 'DATETIME', 'TIMESTAMP',
  'TIME', 'YEAR', 'CHAR', 'VARCHAR', 'TEXT', 'LONGTEXT', 'BINARY', 'VARBINARY',
  'BLOB', 'LONGBLOB', 'JSON', 'ARRAY', 'MAP', 'STRUCT',
  
  // 函数
  'COUNT', 'SUM', 'AVG', 'MIN', 'MAX', 'DISTINCT', 'CASE', 'WHEN', 'THEN', 'ELSE', 'END',
  'IF', 'IFNULL', 'NULLIF', 'COALESCE', 'CONCAT', 'SUBSTRING', 'LENGTH', 'UPPER', 'LOWER',
  'TRIM', 'LTRIM', 'RTRIM', 'REPLACE', 'REGEXP', 'LIKE', 'RLIKE',
  
  // 聚合函数
  'ROW_NUMBER', 'RANK', 'DENSE_RANK', 'LEAD', 'LAG', 'FIRST_VALUE', 'LAST_VALUE',
  'NTILE', 'PERCENT_RANK', 'CUME_DIST',
  
  // 窗口函数
  'OVER', 'PARTITION', 'ROWS', 'RANGE', 'UNBOUNDED', 'PRECEDING', 'FOLLOWING', 'CURRENT',
  
  // 连接
  'JOIN', 'INNER', 'LEFT', 'RIGHT', 'FULL', 'OUTER', 'CROSS', 'ON', 'USING',
  
  // 子查询
  'EXISTS', 'IN', 'NOT', 'ANY', 'ALL', 'SOME',
  
  // 约束
  'PRIMARY', 'KEY', 'FOREIGN', 'REFERENCES', 'UNIQUE', 'CHECK', 'DEFAULT',
  'NULL', 'NOT', 'AUTO_INCREMENT',
  
  // 其他
  'AS', 'ASC', 'DESC', 'BETWEEN', 'AND', 'OR', 'IS', 'UNION', 'INTERSECT', 'EXCEPT',
  'WITH', 'RECURSIVE', 'EXPLAIN', 'DESCRIBE', 'SHOW', 'USE', 'GRANT', 'REVOKE',
  'COMMIT', 'ROLLBACK', 'START', 'TRANSACTION', 'BEGIN', 'SAVEPOINT', 'RELEASE'
]

// Doris内置函数
const DORIS_FUNCTIONS = [
  // 数学函数
  'ABS', 'CEIL', 'CEILING', 'FLOOR', 'ROUND', 'TRUNCATE', 'MOD', 'POWER', 'POW',
  'SQRT', 'EXP', 'LN', 'LOG', 'LOG10', 'LOG2', 'SIN', 'COS', 'TAN', 'ASIN', 'ACOS', 'ATAN',
  'DEGREES', 'RADIANS', 'PI', 'RAND', 'RANDOM', 'SIGN',
  
  // 字符串函数
  'ASCII', 'BIN', 'BIT_LENGTH', 'CHAR_LENGTH', 'CHARACTER_LENGTH', 'CONCAT_WS',
  'ELT', 'EXPORT_SET', 'FIELD', 'FIND_IN_SET', 'FORMAT', 'HEX', 'INSERT',
  'INSTR', 'LCASE', 'LEFT', 'LOCATE', 'LPAD', 'MAKE_SET', 'MID', 'OCT',
  'ORD', 'POSITION', 'QUOTE', 'REPEAT', 'REVERSE', 'RIGHT', 'RPAD',
  'SPACE', 'STRCMP', 'SUBSTR', 'UCASE', 'UNHEX',
  
  // 日期时间函数
  'ADDDATE', 'ADDTIME', 'CONVERT_TZ', 'CURDATE', 'CURRENT_DATE', 'CURRENT_TIME',
  'CURRENT_TIMESTAMP', 'CURTIME', 'DATE', 'DATE_ADD', 'DATE_FORMAT', 'DATE_SUB',
  'DATEDIFF', 'DAYNAME', 'DAYOFMONTH', 'DAYOFWEEK', 'DAYOFYEAR', 'EXTRACT',
  'FROM_DAYS', 'FROM_UNIXTIME', 'GET_FORMAT', 'HOUR', 'LAST_DAY', 'MAKEDATE',
  'MAKETIME', 'MICROSECOND', 'MINUTE', 'MONTH', 'MONTHNAME', 'NOW', 'PERIOD_ADD',
  'PERIOD_DIFF', 'QUARTER', 'SEC_TO_TIME', 'SECOND', 'STR_TO_DATE', 'SUBDATE',
  'SUBTIME', 'SYSDATE', 'TIME', 'TIME_FORMAT', 'TIME_TO_SEC', 'TIMEDIFF',
  'TO_DAYS', 'UNIX_TIMESTAMP', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP',
  'WEEK', 'WEEKDAY', 'WEEKOFYEAR', 'YEAR', 'YEARWEEK',
  
  // 条件函数
  'GREATEST', 'LEAST', 'ISNULL',
  
  // 类型转换函数
  'CAST', 'CONVERT', 'BINARY',
  
  // JSON函数
  'JSON_EXTRACT', 'JSON_UNQUOTE', 'JSON_TYPE', 'JSON_VALID', 'JSON_ARRAY',
  'JSON_OBJECT', 'JSON_MERGE', 'JSON_SET', 'JSON_INSERT', 'JSON_REPLACE',
  'JSON_REMOVE', 'JSON_KEYS', 'JSON_LENGTH'
]

interface MonacoSQLEditorProps {
  value?: string
  onChange?: (value: string) => void
  onExecute?: (sql: string) => void
  height?: string | number
  readOnly?: boolean
  showMinimap?: boolean
  fontSize?: number
  tabSize?: number
  wordWrap?: 'on' | 'off' | 'wordWrapColumn' | 'bounded'
  lineNumbers?: 'on' | 'off' | 'relative' | 'interval'
  folding?: boolean
  autoFormat?: boolean
  placeholder?: string
  connectionId?: string | null
  enableSchemaIntelliSense?: boolean
}

const MonacoSQLEditor: React.FC<MonacoSQLEditorProps> = ({
  value = '',
  onChange,
  onExecute,
  height = 400,
  readOnly = false,
  showMinimap = true,
  fontSize = 14,
  tabSize = 2,
  wordWrap = 'on',
  lineNumbers = 'on',
  folding = true,
  autoFormat = true,
  placeholder = '-- 在此输入SQL语句...\n-- 按 Ctrl+Enter 执行\n-- 按 Ctrl+Shift+F 格式化',
  connectionId = null,
  enableSchemaIntelliSense = true,
}) => {
  const { theme } = useAppSelector(state => state.ui)
  const editorRef = useRef<editor.IStandaloneCodeEditor | null>(null)
  const [isEditorReady, setIsEditorReady] = useState(false)

  // 编辑器挂载时的回调
  const handleEditorDidMount: OnMount = (editorInstance, monaco) => {
    editorRef.current = editorInstance
    setIsEditorReady(true)

    // 注册Doris SQL语言
    registerDorisSQL(monaco)

    // 设置schema智能提示
    if (enableSchemaIntelliSense && connectionId) {
      schemaProvider.setConnectionId(connectionId)
    }

    // 设置编辑器选项
    editorInstance.updateOptions({
      fontSize,
      tabSize,
      wordWrap,
      lineNumbers,
      folding,
      minimap: { enabled: showMinimap },
      readOnly,
      automaticLayout: true,
      scrollBeyondLastLine: false,
      renderWhitespace: 'selection',
      renderControlCharacters: true,
      renderLineHighlight: 'all',
      cursorBlinking: 'smooth',
      cursorSmoothCaretAnimation: true,
      smoothScrolling: true,
      mouseWheelZoom: true,
      contextmenu: true,
      quickSuggestions: {
        other: true,
        comments: false,
        strings: false,
      },
      suggestOnTriggerCharacters: true,
      acceptSuggestionOnEnter: 'on',
      acceptSuggestionOnCommitCharacter: true,
      snippetSuggestions: 'top',
      wordBasedSuggestions: true,
      parameterHints: {
        enabled: true,
        cycle: true,
      },
      hover: {
        enabled: true,
        delay: 300,
      },
    })

    // 添加快捷键
    addKeyboardShortcuts(editorInstance, monaco)

    // 如果有占位符且编辑器为空，显示占位符
    if (!value && placeholder) {
      showPlaceholder(editorInstance, placeholder)
    }
  }

  // 编辑器内容变化回调
  const handleEditorChange: OnChange = (newValue) => {
    if (onChange && newValue !== undefined) {
      onChange(newValue)
    }
  }

  // 注册Doris SQL语言支持
  const registerDorisSQL = (monaco: typeof import('monaco-editor')) => {
    // 注册语言
    monaco.languages.register({ id: 'doris-sql' })

    // 设置语言配置
    monaco.languages.setLanguageConfiguration('doris-sql', {
      comments: {
        lineComment: '--',
        blockComment: ['/*', '*/'],
      },
      brackets: [
        ['{', '}'],
        ['[', ']'],
        ['(', ')'],
      ],
      autoClosingPairs: [
        { open: '{', close: '}' },
        { open: '[', close: ']' },
        { open: '(', close: ')' },
        { open: '"', close: '"' },
        { open: "'", close: "'" },
        { open: '`', close: '`' },
      ],
      surroundingPairs: [
        { open: '{', close: '}' },
        { open: '[', close: ']' },
        { open: '(', close: ')' },
        { open: '"', close: '"' },
        { open: "'", close: "'" },
        { open: '`', close: '`' },
      ],
      folding: {
        markers: {
          start: new RegExp('^\\s*--\\s*#region\\b'),
          end: new RegExp('^\\s*--\\s*#endregion\\b'),
        },
      },
    })

    // 设置语法高亮
    monaco.languages.setMonarchTokensProvider('doris-sql', {
      defaultToken: '',
      tokenPostfix: '.sql',
      ignoreCase: true,

      keywords: DORIS_KEYWORDS,
      functions: DORIS_FUNCTIONS,
      operators: [
        '=', '>', '<', '!', '~', '?', ':', '==', '<=', '>=', '!=',
        '<>', '&&', '||', '++', '--', '+', '-', '*', '/', '&', '|',
        '^', '%', '<<', '>>', '>>>', '+=', '-=', '*=', '/=', '&=',
        '|=', '^=', '%=', '<<=', '>>=', '>>>='
      ],
      builtinFunctions: DORIS_FUNCTIONS,
      builtinVariables: [],
      pseudoColumns: [],

      tokenizer: {
        root: [
          { include: '@comments' },
          { include: '@whitespace' },
          { include: '@pseudoColumns' },
          { include: '@numbers' },
          { include: '@strings' },
          { include: '@complexIdentifiers' },
          { include: '@scopes' },
          [/[;,.]/, 'delimiter'],
          [/[()]/, '@brackets'],
          [/[\w@#$]+/, {
            cases: {
              '@keywords': 'keyword',
              '@functions': 'predefined',
              '@builtinFunctions': 'predefined',
              '@builtinVariables': 'predefined',
              '@default': 'identifier'
            }
          }],
          [/[<>=!%&+\-*/|~^]/, 'operator'],
        ],

        whitespace: [
          [/\s+/, 'white']
        ],

        comments: [
          [/--+.*/, 'comment'],
          [/\/\*/, { token: 'comment.quote', next: '@comment' }]
        ],

        comment: [
          [/[^*/]+/, 'comment'],
          [/\*\//, { token: 'comment.quote', next: '@pop' }],
          [/./, 'comment']
        ],

        pseudoColumns: [
          [/[$][A-Za-z_][\w]*/, 'predefined']
        ],

        numbers: [
          [/0[xX][0-9a-fA-F]*/, 'number'],
          [/[$][+-]*\d*(\.\d*)?/, 'number'],
          [/((\d+(\.\d*)?)|(\.\d+))([eE][\-+]?\d+)?/, 'number']
        ],

        strings: [
          [/'/, { token: 'string', next: '@string' }],
          [/"/, { token: 'string.double', next: '@stringDouble' }],
          [/`/, { token: 'string.backtick', next: '@stringBacktick' }]
        ],

        string: [
          [/[^']+/, 'string'],
          [/''/, 'string'],
          [/'/, { token: 'string', next: '@pop' }]
        ],

        stringDouble: [
          [/[^"]+/, 'string.double'],
          [/""/, 'string.double'],
          [/"/, { token: 'string.double', next: '@pop' }]
        ],

        stringBacktick: [
          [/[^`]+/, 'string.backtick'],
          [/``/, 'string.backtick'],
          [/`/, { token: 'string.backtick', next: '@pop' }]
        ],

        complexIdentifiers: [
          [/\[/, { token: 'identifier.quote', next: '@bracketedIdentifier' }]
        ],

        bracketedIdentifier: [
          [/[^\]]+/, 'identifier'],
          [/]]/, 'identifier'],
          [/]/, { token: 'identifier.quote', next: '@pop' }]
        ],

        scopes: []
      }
    })

    // 设置自动补全
    monaco.languages.registerCompletionItemProvider('doris-sql', {
      provideCompletionItems: (model, position) => {
        const suggestions: languages.CompletionItem[] = []

        // 关键字补全
        DORIS_KEYWORDS.forEach(keyword => {
          suggestions.push({
            label: keyword,
            kind: monaco.languages.CompletionItemKind.Keyword,
            insertText: keyword,
            detail: 'SQL关键字',
            documentation: `SQL关键字: ${keyword}`,
          })
        })

        // 函数补全
        DORIS_FUNCTIONS.forEach(func => {
          suggestions.push({
            label: func,
            kind: monaco.languages.CompletionItemKind.Function,
            insertText: `${func}($0)`,
            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
            detail: 'SQL函数',
            documentation: `SQL函数: ${func}`,
          })
        })

        // 代码片段
        const snippets = [
          {
            label: 'select',
            kind: monaco.languages.CompletionItemKind.Snippet,
            insertText: 'SELECT ${1:columns}\nFROM ${2:table}\nWHERE ${3:condition};',
            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
            detail: 'SELECT语句模板',
            documentation: '基础SELECT查询模板',
          },
          {
            label: 'insert',
            kind: monaco.languages.CompletionItemKind.Snippet,
            insertText: 'INSERT INTO ${1:table} (${2:columns})\nVALUES (${3:values});',
            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
            detail: 'INSERT语句模板',
            documentation: '基础INSERT语句模板',
          },
          {
            label: 'update',
            kind: monaco.languages.CompletionItemKind.Snippet,
            insertText: 'UPDATE ${1:table}\nSET ${2:column} = ${3:value}\nWHERE ${4:condition};',
            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
            detail: 'UPDATE语句模板',
            documentation: '基础UPDATE语句模板',
          },
          {
            label: 'delete',
            kind: monaco.languages.CompletionItemKind.Snippet,
            insertText: 'DELETE FROM ${1:table}\nWHERE ${2:condition};',
            insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
            detail: 'DELETE语句模板',
            documentation: '基础DELETE语句模板',
          },
        ]

        suggestions.push(...snippets)

        return { suggestions }
      }
    })

    // 设置悬停提示
    monaco.languages.registerHoverProvider('doris-sql', {
      provideHover: (model, position) => {
        const word = model.getWordAtPosition(position)
        if (!word) return null

        const upperWord = word.word.toUpperCase()
        
        if (DORIS_KEYWORDS.includes(upperWord)) {
          return {
            range: new monaco.Range(
              position.lineNumber,
              word.startColumn,
              position.lineNumber,
              word.endColumn
            ),
            contents: [
              { value: `**${upperWord}**` },
              { value: `SQL关键字: ${upperWord}` }
            ]
          }
        }

        if (DORIS_FUNCTIONS.includes(upperWord)) {
          return {
            range: new monaco.Range(
              position.lineNumber,
              word.startColumn,
              position.lineNumber,
              word.endColumn
            ),
            contents: [
              { value: `**${upperWord}()**` },
              { value: `SQL函数: ${upperWord}` }
            ]
          }
        }

        return null
      }
    })
  }

  // 添加键盘快捷键
  const addKeyboardShortcuts = (
    editorInstance: editor.IStandaloneCodeEditor,
    monaco: typeof import('monaco-editor')
  ) => {
    // Ctrl+Enter 执行SQL
    editorInstance.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => {
      const value = editorInstance.getValue()
      if (onExecute && value.trim()) {
        onExecute(value)
      }
    })

    // Ctrl+Shift+F 格式化SQL
    editorInstance.addCommand(
      monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KeyF,
      () => {
        if (autoFormat) {
          formatSQLContent()
        }
      }
    )

    // Ctrl+/ 注释切换
    editorInstance.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Slash, () => {
      editorInstance.trigger('keyboard', 'editor.action.commentLine', {})
    })

    // F5 执行SQL
    editorInstance.addCommand(monaco.KeyCode.F5, () => {
      const value = editorInstance.getValue()
      if (onExecute && value.trim()) {
        onExecute(value)
      }
    })
  }

  // 显示占位符
  const showPlaceholder = (editorInstance: editor.IStandaloneCodeEditor, placeholder: string) => {
    const placeholderDecorations = editorInstance.deltaDecorations([], [
      {
        range: new Position(1, 1) as any,
        options: {
          className: 'editor-placeholder',
          isWholeLine: true,
          after: {
            content: placeholder,
            inlineClassName: 'editor-placeholder-text'
          }
        }
      }
    ])

    // 监听内容变化，有内容时移除占位符
    const disposable = editorInstance.onDidChangeModelContent(() => {
      const content = editorInstance.getValue()
      if (content) {
        editorInstance.deltaDecorations(placeholderDecorations, [])
        disposable.dispose()
      }
    })
  }

  // 格式化SQL内容
  const formatSQLContent = () => {
    if (!editorRef.current) return

    const currentValue = editorRef.current.getValue()
    if (!currentValue.trim()) return

    try {
      const formattedSQL = formatSQL(currentValue)
      editorRef.current.setValue(formattedSQL)
    } catch (error) {
      console.error('SQL格式化失败:', error)
    }
  }

  // 公开的方法
  const editorMethods = {
    getValue: () => editorRef.current?.getValue() || '',
    setValue: (value: string) => editorRef.current?.setValue(value),
    focus: () => editorRef.current?.focus(),
    format: formatSQLContent,
    insertText: (text: string) => {
      if (!editorRef.current) return
      const selection = editorRef.current.getSelection()
      if (selection) {
        editorRef.current.executeEdits('insert-text', [{
          range: selection,
          text,
        }])
      }
    },
    getSelectedText: () => {
      if (!editorRef.current) return ''
      const selection = editorRef.current.getSelection()
      if (selection) {
        return editorRef.current.getModel()?.getValueInRange(selection) || ''
      }
      return ''
    },
  }

  // 监听connectionId变化，更新schema提示
  useEffect(() => {
    if (enableSchemaIntelliSense) {
      schemaProvider.setConnectionId(connectionId)
    }
  }, [connectionId, enableSchemaIntelliSense])

  // 暴露编辑器方法给父组件
  useEffect(() => {
    if (isEditorReady && editorRef.current) {
      // 可以通过ref暴露方法给父组件
      ;(editorRef.current as any).editorMethods = editorMethods
    }
  }, [isEditorReady])

  return (
    <div style={{ height, border: '1px solid #d9d9d9', borderRadius: 6 }}>
      <Editor
        height="100%"
        language="doris-sql"
        theme={theme === 'dark' ? 'vs-dark' : 'vs'}
        value={value}
        onChange={handleEditorChange}
        onMount={handleEditorDidMount}
        options={{
          selectOnLineNumbers: true,
          roundedSelection: false,
          readOnly,
          cursorStyle: 'line',
          automaticLayout: true,
        }}
      />
    </div>
  )
}

export default MonacoSQLEditor